package tmt.usercenter.web.domain;

import com.tmt.fileservice.FileSaveMode;
import com.tmt.fileservice.IFileDispatcher;
import com.tmt.fileservice.IFileService;
import com.tmt.fileservice.impl.DefaultFileDispatcher;
import com.tmt.fileservice.impl.DefaultFileService;
import com.tmt.helper.ReflectHelper;
import com.tmt.helper.StringHelper;
import com.tmt.jpafieldvalueconvert.impl.FileUrlFieldConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tmt.usercenter.web.common.Const;

import javax.persistence.Column;
import java.lang.reflect.Field;
import java.text.MessageFormat;


/**
 * 本类用反射方式实例化的
 * Created by ThreeManTeam on 2017/5/22.
 */
public class TmtFileUrlFieldConverter extends FileUrlFieldConverter {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public <T> boolean support(T obj, String propName, String eventName) {
        return true;
    }

    @Override
    @Transactional(readOnly = true)
    public <T> void convertToDatabaseColumn(T obj, String propName, String eventName) {
        try {
            IFileDispatcher ifDispatcher = DefaultFileDispatcher.getInstance();
            String address = ifDispatcher.getHostUrl() + ifDispatcher.getContextPath();

            //如果是外部链接，则不进行处理。
            Object value = ReflectHelper.getFieldValue(obj, propName);
            if (value != null
                    && (value.toString().toLowerCase().startsWith("http://") || value.toString().toLowerCase().startsWith("https://"))
                    && !value.toString().toLowerCase().startsWith(address.toLowerCase()))
                return;

            if (value == null || value.toString().trim().isEmpty())
                return;

            //如果value为null或空或默认图片，则将字段值直接设置为NULL.
            String defaultValue = getDefaultFileUrl(address, obj, propName);
            if (value.equals(defaultValue)){
                Field field = ReflectHelper.findFieldByName(obj.getClass(), propName);
                value = field.getAnnotation(Column.class).nullable() ?  null :  getDefaultFileName(obj.getClass(), propName);
                ReflectHelper.setFieldValue(obj, propName, value);
                return;
            }

            String path = ifDispatcher.getFilePath(obj, propName, null, FileSaveMode.PERSIST);
            String[] paths = StringHelper.splitWithoutEmpty(path, "/");
            ReflectHelper.setFieldValue(obj, propName, paths[paths.length - 1]);
        }catch (Exception ex){
            logger.debug(MessageFormat.format("JPA事件:{0}->{1}->{2}", eventName, propName, ex.getMessage()));
        }
    }

    @Override
    @Transactional(readOnly = true)
    public <T> void convertToEntityAttribute(T obj, String propName, String eventName) {
        try {
            IFileDispatcher ifDispatcher = DefaultFileDispatcher.getInstance();
            String address = ifDispatcher.getHostUrl() + ifDispatcher.getContextPath();

            //如果是外部链接，则不进行处理。
            Object value = ReflectHelper.getFieldValue(obj, propName);
            if (value != null
                    && (value.toString().toLowerCase().startsWith("http://") || value.toString().toLowerCase().startsWith("https://"))
                    && !value.toString().toLowerCase().startsWith(address.toLowerCase()))
                return;

            String fileName = getDefaultFileName(obj.getClass(), propName);
            if (value == null || value.toString().trim().isEmpty() || value.equals(fileName)){
                ReflectHelper.setFieldValue(obj, propName, getDefaultFileUrl(address, obj, propName));
            }else {
                String url = ifDispatcher.getFileUrl(obj, propName, FileSaveMode.PERSIST);
                ReflectHelper.setFieldValue(obj, propName, url);

                IFileService fileService = DefaultFileService.getInstance();
                String path = ifDispatcher.fileUrlToPath(url);
                switch (eventName){
                    case "PostUpdate":
                        //修改实体时，同步删除实体之前绑定的废弃文件。
                        fileService.deleteFileExclude(path);
                        break;
                    case "PostRemove":
                        //删除实体时，同步删除实体绑定的文件。
                        fileService.deleteFile(path);
                        break;
                }
            }
        }catch (Exception ex){
            logger.debug(MessageFormat.format("JPA事件:{0}->{1}->{2}", eventName, propName, ex.getMessage()));
        }
    }

    public static <T> String getDefaultFileUrl(String hostAddress, Class clazz, String propName){
        return MessageFormat.format("{0}{1}{2}", hostAddress, Const.DEFAULT_IMG_URI, getDefaultFileName(clazz, propName));
    }

    private static <T> String getDefaultFileUrl(String hostAddress, T obj, String propName){
        return getDefaultFileUrl(hostAddress, obj.getClass(), propName);
    }

    private static <T> String getDefaultFileName(Class clazz, String propName){
        String fileName = "{0}{1}_{2}{3}";
        fileName = MessageFormat.format(fileName, Const.DEFAULT_IMG_PREFIX,
                clazz.getSimpleName(), propName, Const.DEFAULT_IMG_SUFFIX);
        return fileName;
    }

}
